package com.itheima.reggie.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.reggie.dto.SetmealDto;
import com.itheima.reggie.entity.Category;
import com.itheima.reggie.entity.PageParam;
import com.itheima.reggie.entity.Setmeal;
import com.itheima.reggie.entity.SetmealDish;
import com.itheima.reggie.exception.CustomException;
import com.itheima.reggie.mapper.SetMealMapper;
import com.itheima.reggie.service.CategoryService;
import com.itheima.reggie.service.SetMealDishService;
import com.itheima.reggie.service.SetMealService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

@Service
@Transactional
public class SetMealServiceImpl implements SetMealService {
    
    @Autowired
    private SetMealMapper mapper;
    
    @Autowired
    private SetMealDishService setMealDishService;
    
    @Autowired
    private CategoryService categoryService;


    /**
     * 修改套餐状态
     *
     * @param setmeal
     * @return
     */
    @Override
    public int updateStatus(Setmeal setmeal) {
        return mapper.updateById(setmeal);
    }

    /**
     * 修改套餐
     *
     * @param setmealDto
     * @return
     */
    @Override
    public int update(SetmealDto setmealDto) {
        //1. 更新套餐
        int rows = mapper.updateById(setmealDto);

        //2. 更新套餐里的菜品
        //2.1 删除菜品数据
        setMealDishService.deleteBySetmealId(setmealDto.getId());

        int rows2 = 0;
        //2.2 执行菜品添加
        List<SetmealDish> setmealDishes = setmealDto.getSetmealDishes();
        if (setmealDishes != null && setmealDishes.size() > 0) {

            for (SetmealDish setmealDish : setmealDishes) {
                //设置菜品属于哪一个套餐
                setmealDish.setSetmealId(setmealDto.getId());

                rows2 += setMealDishService.add(setmealDish);
            }
            return rows > 0 && rows2 == setmealDishes.size() ? 1 : 0;
        }
        return rows;
    }

    /**
     * 删除套餐（包含单个删除和批量删除）

     * @param ids
     * @return
     */
    @Override
    public int delete(List<Long> ids) {
        //1. 先查询这一批id里面有没有套餐是启售状态，如果是，那么直接抛出异常！。
        LambdaQueryWrapper<Setmeal> qw  = new LambdaQueryWrapper<>();
        qw.eq(Setmeal::getStatus , 1); //查询状态为启售状态
        qw.in(Setmeal::getId , ids);
    
        //1.1 查询数量： 在这些id里面，启售的数量有几个
        int count = mapper.selectCount(qw);
        if(count > 0){
            throw  new  CustomException("套餐包含启售状态，禁止删除！");
        }
        
        //2. 如果到了这里，就表示这些套餐都是停售状态，那么直接删除即可。
        
        //2.1 先删除套餐表
        int row = mapper.deleteBatchIds(ids);
        
        //2.2 后删除套餐菜品表
        for (Long id : ids) {
            setMealDishService.deleteBySetmealId(id);
        }
    
        return row  ;
    }
    
    /**
     * 分页查询套餐
     *
     * @param pageParam
     * @return
     */
    @Override
    public IPage<SetmealDto> findPage(PageParam pageParam) {
        
        //1. 先去查询套餐表，得到分页数据。
        IPage<Setmeal> p = new Page<>(pageParam.getPage() , pageParam.getPageSize());
        
        //1.1 设置搜索条件
        LambdaQueryWrapper<Setmeal> qw = new LambdaQueryWrapper<>();
        qw.like(pageParam.getName() != null , Setmeal::getName , pageParam.getName());
        
        //1.2 执行查询
        mapper.selectPage(p , qw);
        
        //2. 创建IPage<SetmealDto>
        IPage<SetmealDto> dtoIPage = new Page<>();
        
        //2.1 设置total
        dtoIPage.setTotal(p.getTotal());
        
        //2.2 设置records;
        
        //2.2.1 遍历集合
        List<SetmealDto> dtoList = p.getRecords().stream().map(setmeal -> {
            
            //a. 创建一个SetMealDto
            SetmealDto dto = new SetmealDto();
            
            //b. 把setmeal拷贝到dto上
            BeanUtils.copyProperties(setmeal , dto);
            
            //c. 查询套餐的数据，设置分类的名称
            Category category = categoryService.findById(setmeal.getCategoryId());
            dto.setCategoryName(category.getName());
            
            //d. 返回dto 以便这些dto能够装到后面产出的集合里面
            return dto;
        }).collect(Collectors.toList());
    
        dtoIPage.setRecords(dtoList);
        
        return dtoIPage;
    }
    
    /**
     * 新增套餐

     * @param setmealDto
     * @return
     */
    @Override
    public int add( SetmealDto setmealDto) {
        
        //1. 先往套餐表添加基本数据
        int row = mapper.insert(setmealDto);
        
        //2. 往套餐菜品表添加数据
        List<SetmealDish> dishList = setmealDto.getSetmealDishes();
        
        int row2 = 0 ;
        if(dishList != null && dishList.size() > 0 ){
            for (SetmealDish setmealDish : dishList) {
        
                //设置这个菜品属于哪一个套餐
                setmealDish.setSetmealId(setmealDto.getId());
    
                row2 += setMealDishService.add(setmealDish);
            }
            return row >0 && row2 == dishList.size() ? 1 : 0;
        }
        return row ;
    }
    
    /**
     * 根据分类id来查询套餐表，查询这个分类在套餐表里面的总数
     *
     * @param categoryId
     * @return
     */
    @Override
    public int findCountByCategoryId(long categoryId) {
        
        //1. 创建条件对象
        LambdaQueryWrapper<Setmeal> qw = new LambdaQueryWrapper<>();
        qw.eq(Setmeal::getCategoryId , categoryId);
        
        //2. 执行查询
        return mapper.selectCount(qw);
    }

    /**
     * 根据分类id和状态查询套餐数据
     *
     * @param categoryId
     * @param status
     * @return
     */
    @Override
    public List<Setmeal> findCategoryId(Long categoryId, Integer status) {

        //构建查询条件
        LambdaQueryWrapper<Setmeal> lqw = new LambdaQueryWrapper<>();
        lqw.eq(categoryId != null, Setmeal::getCategoryId, categoryId);
        lqw.eq(status != null, Setmeal::getStatus, status);

        return mapper.selectList(lqw);
    }

}
